fix: parse email verification id in exception#485
Merged
nicknisi merged 3 commits intoworkos:mainfrom Oct 15, 2025
Merged
Conversation
Fixes workos#309 When authenticate_with_password() raises an AuthorizationException for an unverified email, the API response includes an email_verification_id field. This field is now properly extracted and accessible on the exception object, eliminating the need to manually parse the response JSON. Co-Authored-By: Deep Singhvi <deep@buildwithfern.com>
…xception - Created EmailVerificationRequiredException subclass of AuthorizationException - Added email_verification_id field specific to this exception type - Updated HTTP client to detect email_verification_required error code and raise specific exception - Added tests for both the new exception and to verify regular AuthorizationException still works - All 370 tests pass Co-Authored-By: Deep Singhvi <deep@buildwithfern.com>
Contributor
There was a problem hiding this comment.
Greptile Overview
Summary
Adds proper handling for the email_verification_id field returned by WorkOS API when email verification is required during password authentication.
Key Changes:
- Created new
EmailVerificationRequiredExceptionsubclass ofAuthorizationExceptioninworkos/exceptions.py:48-63that extracts and stores theemail_verification_idfield - Modified
_maybe_raise_error_by_status_code()inworkos/utils/_base_http_client.py:102-108to detect 403 responses with codeemail_verification_requiredand raise the specific exception - Added comprehensive tests in
tests/test_sync_http_client.py:267-316to verify both the new exception and that regular authorization exceptions still work correctly
Issue Found:
- Missing equivalent tests in
tests/test_async_http_client.py- the async HTTP client uses the sameBaseHTTPClient._maybe_raise_error_by_status_code()method, so it will work correctly, but test coverage is incomplete
Confidence Score: 4/5
- This PR is safe to merge with one test coverage gap
- The implementation correctly solves the issue by adding a specific exception type that inherits from
AuthorizationExceptionand extracts theemail_verification_idfield. The logic properly checks for the specific error code before raising the specialized exception, ensuring backward compatibility. Comprehensive sync tests verify the behavior. Score reduced by 1 point due to missing async test coverage, though the functionality will work correctly since both sync and async clients share the same exception handling logic - tests/test_async_http_client.py requires equivalent test coverage for
EmailVerificationRequiredException
Important Files Changed
File Analysis
| Filename | Score | Overview |
|---|---|---|
| workos/exceptions.py | 5/5 | Added EmailVerificationRequiredException class with email_verification_id field - clean implementation following existing patterns |
| workos/utils/_base_http_client.py | 5/5 | Added conditional logic to raise EmailVerificationRequiredException for 403 responses with code email_verification_required |
| tests/test_sync_http_client.py | 4/5 | Added comprehensive tests for new exception, but missing equivalent tests in async test file |
Sequence Diagram
sequenceDiagram
participant Client as User Code
participant UM as UserManagement
participant HTTP as BaseHTTPClient
participant API as WorkOS API
Client->>UM: authenticate_with_password(email, password)
UM->>HTTP: request(path="/user_management/authenticate", json={...})
HTTP->>API: POST /user_management/authenticate
alt Email Verification Required
API-->>HTTP: 403 {code: "email_verification_required", email_verification_id: "..."}
HTTP->>HTTP: Check if code == "email_verification_required"
HTTP-->>UM: Raise EmailVerificationRequiredException(email_verification_id)
UM-->>Client: EmailVerificationRequiredException
Note over Client: Can access ex.email_verification_id
else Other 403 Error
API-->>HTTP: 403 {code: "forbidden", message: "..."}
HTTP-->>UM: Raise AuthorizationException
UM-->>Client: AuthorizationException
else Success
API-->>HTTP: 200 {user: {...}, access_token: "..."}
HTTP-->>UM: Return response_json
UM-->>Client: AuthenticationResponse
end
Additional Comments (1)
-
tests/test_async_http_client.py, line 8-13 (link)logic: missing import and tests for
EmailVerificationRequiredExceptionin async tests
3 files reviewed, 1 comment
nicknisi
approved these changes
Oct 15, 2025
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Solves #309 and correctly parses
email_verification_id.Documentation
Does this require changes to the WorkOS Docs? E.g. the API Reference or code snippets need updates.
If yes, link a related docs PR and add a docs maintainer as a reviewer. Their approval is required.